﻿using Domain.Entity;
using Domain.Entity.Aprove;
using DtoFw;
using DtoFw.Enum;
using DtoFw.Query;
using DtoFw.Result;
using Repository;
using Service.Base;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Util;

namespace Service
{
    public class CasePhysicalApproveService : BaseService
    {
        private readonly CasePhysicalApproveRepository _ApproveRepository;
        private readonly SnowFlakeGenerator _snowFlakeGenerator;
        private readonly CasePhysicalApproveListRepository _ListRepository; 
        public CasePhysicalApproveService(CasePhysicalApproveRepository _ApproveRepository, SnowFlakeGenerator snowFlakeGenerator,
            CasePhysicalApproveListRepository _ListRepository, MainSerialNumberRepository mainSerialNumberRepository) : base(mainSerialNumberRepository)
        {
            this._ApproveRepository = _ApproveRepository;
            this._ListRepository = _ListRepository;
            this._snowFlakeGenerator = snowFlakeGenerator;
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <returns></returns>
        public BaseResult Post(CasePhysicalApproveReqDto reqDto)
        {
            var app = QueryFlowConfigXp(reqDto.OrganId);
            if (app.auditLs == null || app.auditLs.Count == 0)
            {
                return BaseGenericResult<dynamic>.Failure(new object(), "未配置审核人员，新增失败");
            }
            var examPerson = app.auditLs[0];

            var entity = AutoMapperExtension.MapTo<CasePhysicalApproveReqDto, CasePhysicalApproveEntity>(reqDto);
            entity.Sn = base.GetNumber(reqDto.OrganId, DtoFw.Enum.EnumSystemNumber.SPBH);
            entity.Creator = entity.Modifyer = reqDto.UserName;
            entity.CreatorId = entity.ModifyerId = reqDto.UserId;
            entity.CreateTime = entity.ModifyerTime = DateTime.Now;
            entity.ExamId = string.Join(",", examPerson.person);
            entity.ExamSeq = examPerson.seq;
            if (_ApproveRepository.Insert(entity) > 0)
            {
                //物证明细
                var item = new CasePhysicalApproveListEntity()
                {
                    ApproveId = entity.Id,
                    CaseId = entity.CaseId,
                    CreateTime = entity.CreateTime,
                    Creator = entity.Creator,
                    CreatorId = entity.CreatorId,
                    Modifyer = entity.Modifyer,
                    ModifyerId = entity.ModifyerId,
                    ModifyerTime = entity.ModifyerTime
                };
                foreach (var id in reqDto.ids)
                {
                    item.EvidenceId = id;
                    _ListRepository.Insert(item);
                }
                //日志
                CasePhysicalApproveLogEntity log = new CasePhysicalApproveLogEntity()
                {
                    ApproveId = entity.Id,
                    CreateTime = entity.CreateTime,
                    Creator = entity.Creator,
                    CreatorId = entity.CreatorId ?? 0,
                    Reason = "",
                    Remark = "申请"
                };
                _ApproveRepository.Insert(log);
                if (!string.IsNullOrEmpty(entity.ExamId))
                {
                    string msg = $"您有一个出库审批（{entity.Sn}），请及时处理！";
                    Notice(msg, new EvidenceQueryReqDto() { CurrentUser = reqDto.CurrentUser, Id = entity.Id });
                }
                return BaseResult.Succeed();
            }
            return BaseResult.Failure("新增审核失败");
        }

        /// <summary>
        /// 编辑
        /// </summary>
        /// <returns></returns>
        public BaseResult Put(CasePhysicalApproveReqDto reqDto)
        {
            var entity = _ApproveRepository.GetDb().Queryable<CasePhysicalApproveEntity>().First(x => x.Id == reqDto.Id);
            if (entity == null)
                return BaseResult.Failure("未查询到申请记录");
            entity = AutoMapperExtension.MapTo<CasePhysicalApproveReqDto, CasePhysicalApproveEntity>(reqDto, entity);
            entity.Modifyer = reqDto.UserName;
            entity.ModifyerId = reqDto.UserId;
            entity.ModifyerTime = DateTime.Now;
            if (_ApproveRepository.Save(entity).Id > 0)
            {
                //物证明细
                var item = new CasePhysicalApproveListEntity()
                {
                    ApproveId = entity.Id,
                    CaseId = entity.CaseId,
                    CreateTime = entity.CreateTime,
                    Creator = entity.Creator,
                    CreatorId = entity.CreatorId,
                    Modifyer = entity.Modifyer,
                    ModifyerId = entity.ModifyerId,
                    ModifyerTime = entity.ModifyerTime
                };
                var rows = _ListRepository.GetList(entity.Id);
                foreach (var id in reqDto.ids)
                {
                    if(rows.Any(v=>v.EvidenceId == id))
                    {
                        item.EvidenceId = id;
                        _ListRepository.Insert(item);
                    }
                }
                var dels = rows.Where(v => !reqDto.ids.Contains(v.EvidenceId)).ToList();
                foreach (var r in dels)
                {
                    r.IsDeleted = true;
                    r.Modifyer = entity.Modifyer;
                    r.ModifyerId = entity.ModifyerId;
                    r.ModifyerTime = entity.ModifyerTime;
                    _ListRepository.Save(r);
                } 
                //日志
                CasePhysicalApproveLogEntity log = new CasePhysicalApproveLogEntity()
                {
                    ApproveId = entity.Id,
                    CreateTime = entity.CreateTime,
                    Creator = entity.Creator,
                    CreatorId = entity.CreatorId ?? 0,
                    Reason = "",
                    Remark = "修改"
                };
                _ApproveRepository.Insert(log);
                return BaseResult.Succeed();
            }
            return BaseResult.Failure("审核信息修改失败");
        }
        /// <summary>
        /// 编辑
        /// </summary>
        /// <returns></returns>
        public BaseResult Delete(CasePhysicalApproveReqDto reqDto)
        {
            foreach (var id in reqDto.ids)
            {
                var entity = _ApproveRepository.GetDb().Queryable<CasePhysicalApproveEntity>().First(x => x.Id == id);
                if (entity == null)
                    return BaseResult.Failure("未查询到申请记录");
                entity = AutoMapperExtension.MapTo<CasePhysicalApproveReqDto, CasePhysicalApproveEntity>(reqDto, entity);
                entity.Modifyer = reqDto.UserName;
                entity.ModifyerId = reqDto.UserId;
                entity.ModifyerTime = DateTime.Now;
                entity.IsDeleted = true;
                if (_ApproveRepository.Save(entity).Id > 0)
                {
                    //物证明细
                    var item = new CasePhysicalApproveListEntity()
                    {
                        ApproveId = entity.Id,
                        CaseId = entity.CaseId,
                        CreateTime = entity.CreateTime,
                        Creator = entity.Creator,
                        CreatorId = entity.CreatorId,
                        Modifyer = entity.Modifyer,
                        ModifyerId = entity.ModifyerId,
                        ModifyerTime = entity.ModifyerTime
                    };
                    var rows = _ListRepository.GetList(entity.Id);
                    foreach (var r in rows)
                    {
                        r.IsDeleted = true;
                        r.Modifyer = entity.Modifyer;
                        r.ModifyerId = entity.ModifyerId;
                        r.ModifyerTime = entity.ModifyerTime;
                        _ListRepository.Save(r);
                    }
                    //日志
                    CasePhysicalApproveLogEntity log = new CasePhysicalApproveLogEntity()
                    {
                        ApproveId = entity.Id,
                        CreateTime = entity.CreateTime,
                        Creator = entity.Creator,
                        CreatorId = entity.CreatorId ?? 0,
                        Reason = "",
                        Remark = "删除"
                    };
                    _ApproveRepository.Insert(log);

                }
            }
            return BaseResult.Succeed();
        }
        /// <summary>
        /// 单个查询
        /// </summary>
        /// <returns></returns>
        public BaseGenericResult<dynamic> Get(CasePhysicalApproveReqDto reqDto)
        {
            var entity = _ApproveRepository.GetDb().Queryable<CasePhysicalApproveEntity>().First(x => x.Id == reqDto.Id);
            if (entity == null)
                return BaseGenericResult<dynamic>.Failure(new object(), "未查询到审核信息");
            return BaseGenericResult<dynamic>.Succeed(new { 
                data = entity, 
                caseInfo = _ApproveRepository.GetDb().Queryable<CaseEntity>().First(x => x.Id == entity.CaseId),
                rows = _ListRepository.QueryList(entity.Id),
                logLst = this._ApproveRepository.QueryLog(entity.Id).OrderByDescending(v=>v.Id)
            });
        }
        /// <summary>
        /// 分页
        /// </summary>
        /// <returns></returns>
        public BaseGenericResult<Pager<object>> Pager(CasePhysicalApproveReqDto query)
        {
            int total = 0;
            var pager = _ApproveRepository.GetDb().Queryable<CasePhysicalApproveEntity, CaseEntity>((x, y) =>
                      new JoinQueryInfos(JoinType.Left, x.CaseId == y.Id && !x.IsDeleted && !y.IsDeleted))
                    .Where((x, y) => y.OrganId == query.OrganId)
                    .WhereIF(!string.IsNullOrWhiteSpace(query.Sn), (x, y) => x.Sn == query.Sn)
                    .WhereIF(!string.IsNullOrWhiteSpace(query.CaseNo), (x, y) => y.CaseNo == query.CaseNo)
                    .WhereIF(!string.IsNullOrWhiteSpace(query.CaseName), (x, y) => y.CaseName == (query.CaseName))
                    .WhereIF(query.State > -1, (x) => x.State == query.State)
                    .OrderBy(x => x.CreateTime, OrderByType.Desc)
                    .Select((x, y) => new CasePhysicalApproveEntity
                    {
                        Id = x.Id,
                        CaseNo = y.CaseNo,
                        InspectionNo = y.InspectionNo,
                        CaseName = y.CaseName,
                        CaseTime = y.CaseTime,
                        Sn = x.Sn,
                        TargetDept = x.TargetDept,
                        TargetPerson = x.TargetPerson,
                        TargetMobile = x.TargetMobile,
                        Reason = x.Reason,
                        Ty = x.Ty,
                        Remark = x.Remark,
                        State = x.State,
                        ExamId = x.ExamId,
                        ExamPerson = x.ExamPerson,
                        ExamTime = x.ExamTime,
                        Creator = x.Creator,
                        CreateTime = x.CreateTime,
                        Modifyer = x.Modifyer,
                        ModifyerTime = x.ModifyerTime,
                    }).ToPageList(query.Page, query.PageSize, ref total);
            foreach (var item in pager)
            {
                if (item.State < 2)
                {
                    item.IsAllowCancel = true;
                }
                else if(item.State == 2)
                {
                    long id = item.Id;
                    item.IsAllowCancel = _ListRepository.IsAny(v => v.ApproveId == id && v.PassSt == 1 && !v.IsUsed);
                }
            }
            BaseGenericResult<Pager<object>> baseGeneric = new BaseGenericResult<Pager<object>>();
            baseGeneric.Data = new Pager<object>();
            baseGeneric.Data.Data = pager.ToList<object>();
            baseGeneric.Data.TotalCount = total;
            return baseGeneric;
        }
        /// <summary>
        /// 审核
        /// </summary>
        public BaseResult Approvesubmit(CasePhysicalApproveReqDto query)
        {
            var entity = _ApproveRepository.GetDb().Queryable<CasePhysicalApproveEntity>().First(x => x.Id == query.Id);
            if (entity == null)
                return BaseGenericResult<dynamic>.Failure(new object(), "未查询到审核信息");
            var app = QueryFlowConfigXp(query.OrganId);
            if (app.auditLs == null || app.auditLs.Count == 0)
            {
                return BaseGenericResult<dynamic>.Failure(new object(), "未配置审核人员，新增失败");
            }
            var examPerson = app.auditLs.Where(v=>v.seq > entity.ExamSeq).FirstOrDefault();

            entity.State = query.State;
            entity.Modifyer = query.UserName;
            entity.ModifyerTime = DateTime.Now;
            entity.ModifyerId = query.UserId;
            string reason = "审核中";
            int passst = 0;
            if(entity.State == 2 || entity.State == 3)
            {
                if(entity.State == 2)
                {
                  
                    if (examPerson != null)
                    {
                        entity.ExamSeq = examPerson.seq;
                        entity.ExamId = string.Join(",",examPerson.person);
                        entity.State = 1;
                    }
                    else
                    {
                        passst = 1;
                        reason = "审核通过";
                        //已无后序审核人，设置成终审
                        entity.ExamId = "";
                    }
                }
                else
                {
                    passst = 3;
                    reason = "审核不同意";
                    entity.ExamId = "";
                }
                entity.ExamTime = DateTime.Now;
                entity.ExamPerson = query.UserName;
            }
            //日志
            CasePhysicalApproveLogEntity log = new CasePhysicalApproveLogEntity()
            {
                ApproveId = entity.Id,
                CreateTime = entity.ModifyerTime,
                Creator = entity.Modifyer,
                CreatorId = entity.ModifyerId ?? 0,
                Reason = reason,
                Remark = query.Remark
            };
            _ApproveRepository.Save(entity);
            _ApproveRepository.Insert(log);

            var rows = _ListRepository.GetList(entity.Id);
            foreach (var item in rows)
            {
                item.Modifyer = entity.Modifyer;
                item.ModifyerId = entity.ModifyerId;
                item.ModifyerTime = entity.ModifyerTime;
                item.PassSt = passst;
                _ListRepository.Save(item);
            }
            if(entity.State == 1 && !string.IsNullOrEmpty(entity.ExamId))
            {
                string msg = $"您有一个出库审批（{entity.Sn}），请及时处理！";
                Notice(msg, new EvidenceQueryReqDto() { CurrentUser = query.CurrentUser, Id = entity.Id });
            }
            return BaseResult.Succeed();
        }
        /// <summary>
        ///  取消
        /// </summary>
        /// <returns></returns>
        public BaseResult CancelApprove(CasePhysicalApproveReqDto query)
        {
            var entity = _ApproveRepository.GetDb().Queryable<CasePhysicalApproveEntity>().First(x => x.Id == query.Id);
            if (entity == null)
                return BaseGenericResult<dynamic>.Failure(new object(), "未查询到审核信息");
            
            entity.State = 9;
            entity.Modifyer = query.UserName;
            entity.ModifyerTime = DateTime.Now;
            entity.ModifyerId = query.UserId;
            string reason = "撤销";
            //日志
            CasePhysicalApproveLogEntity log = new CasePhysicalApproveLogEntity()
            {
                ApproveId = entity.Id,
                CreateTime = entity.ModifyerTime,
                Creator = entity.Modifyer,
                CreatorId = entity.ModifyerId ?? 0,
                Reason = reason,
                Remark = query.Remark
            };
            _ApproveRepository.Save(entity);
            _ApproveRepository.Insert(log);

            var rows = _ListRepository.GetList(entity.Id);
            foreach (var item in rows)
            {
                if(item.PassSt == 2 && item.IsUsed)
                {
                    continue;
                }
                item.Modifyer = entity.Modifyer;
                item.ModifyerId = entity.ModifyerId;
                item.ModifyerTime = entity.ModifyerTime;
                item.PassSt = 9;
                _ListRepository.Save(item);
            }
            return BaseResult.Succeed();
        }

        /// <summary>
        /// 审批审核，查询可申请的物品
        /// </summary>
        /// <param name="reqDto"></param>
        /// <returns></returns>
        public BaseGenericResult<Pager<DtoFw.Result.CaseEvidencePagerRespDto>> QueryApproveEvidence(EvidenceQueryReqDto reqDto)
        {
            BaseGenericResult<Pager<DtoFw.Result.CaseEvidencePagerRespDto>> page = new BaseGenericResult<Pager<CaseEvidencePagerRespDto>>();
            page.Data = _ListRepository.QueryCaseEvidences(reqDto);
            page.Success = true;
            return page;
        }
        /// <summary>
        /// 检查是否可以出库
        /// </summary>
        public BaseGenericResult<object> CheckEvidenceAuditState(CasePhysicalApproveReqDto query)
        {
            BaseGenericResult<object> page = new BaseGenericResult<object>();
            ApproveConfigEntity app = QueryFlowConfigXp(query.OrganId);
            if (app.audit)
            {
                //查询物品审核状态
                var lst = _ListRepository.CheckEvidenceAuditState(query.ids, query.Ty).Select(v=>v.EvidenceId).ToList();
                page.Data = lst;
            }
            else
            {
                //无需审核，原样返回
                page.Data = query.ids;
            }
            page.Success = true;
            return page;
        }
        /// <summary>
        /// 查询流程配置
        /// </summary>
        public ApproveConfigEntity QueryFlowConfigXp(long organId)
        {
            var ret = new ApproveConfigEntity();
            var r1 = _ListRepository.GetDb().Queryable<MainConfigEntity>().Where(t => t.CategoryCode == EnumClass.FlowConfig && t.Class == EnumClass.FlowConfig && !t.IsDeleted && t.OrganId == organId).First();
            if (r1 != null && !string.IsNullOrEmpty(r1.Content))
            {
                ret = Newtonsoft.Json.JsonConvert.DeserializeObject<ApproveConfigEntity>(r1.Content);
                ret.auditLs = ret.auditLs.OrderBy(v=>v.seq).ToList();
            }
            return ret;
        }

        /// <summary>
        /// 数据推送UI
        /// </summary>
        /// <param name="dto"></param>
        private void SendWarning(WebScoketReqDto dto, string userCode)
        {
            if (dto != null && dto.webScoketContents != null && dto.webScoketContents.Count > 0)
            {
                WebSocketModel.SendWarning(dto, new List<string>() { userCode });
            }
        }


        public void Notice(string content, EvidenceQueryReqDto entity)
        {
            _ApproveRepository.GetDb().Insertable(new NotificationEntity()
            {
                Mold = (int)EalyWarnTypeEnum.eAuditingWarning,
                NoticeTime = DateTime.Now,
                Describe = content,
                Level = 3,
                IsHandle = 1,
                IsIgnore = 1,
                Influence = "请尽快审核",
                TreatmentMethod = "请至审核模块",
                OrganId = entity.OrganId,
                OrganName = entity.OrganName,
                ComNo = entity.ComNo,
                CheckId = entity.Id, // 箱子ID
                CreateTime = DateTime.Now,
                IsDeleted = false
            }).ExecuteCommandAsync();

            WebScoketReqDto dto = new WebScoketReqDto();

            //推送
            dto.webScoketContents.Add(new WebScoketContent
            {
                Mold = (int)EalyWarnTypeEnum.eStockQuantityWarning,
                MolldTitle = "审核提醒",
                NoticeTime = DateTime.Now,
                Describe = content,
                Level = 3,
            });

            SendWarning(dto, entity.UserCode);
        }
    }
}
                     